package com.bee.app.vo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.bee.app.sign.SignKit;
import com.bee.app.util.FastJsonUtil;

/**
 * 所有Vo对象的基类, Null,"",transient的属性不参与签名
 *
 * @author liuzy
 * @since 2015年6月4日
 */
public class BaseVo {

	private String code = "0000";

	private String message = "请求成功";

	private long timestamp = new Date().getTime();

	private String signature;

	public BaseVo() {

	}

	public BaseVo(String code_msg) {
		if (code_msg.contains("_")) {
			this.code = code_msg.split("_")[0];
			this.message = code_msg.split("_")[1];
		} else {
			this.code = code_msg;
		}
	}

	public BaseVo(String code, String message) {
		this.code = code;
		this.message = message;
	}

	/**
	 * 给自己签名
	 *
	 * @return
	 */
	public String sign() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("code", code);
		map.put("message", message);
		map.put("timestamp", Long.toString(timestamp));
		Field[] fields = this.getClass().getDeclaredFields();
		for (Field field : fields) {
			String name = field.getName();
			if (SignKit.SIGNKEY.equals(name)) {
				continue;
			}
			if (Modifier.isTransient(field.getModifiers())) {
				continue;
			}
			Object value = getFieldValueByName(name, this);
			if (value == null || value == "") {
				continue;
			}
			map.put(name, FastJsonUtil.toJSON(value));
		}
		return this.signature = SignKit.sign(map);
	}

	/**
	 * 自签名返回
	 *
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T extends BaseVo> T signed() {
		this.sign();
		return (T) this;
	}

	/**
	 * 根据属性名称取得对象对应属性的值
	 *
	 * @param fieldName
	 * @param o
	 * @return
	 */
	private Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + fieldName.substring(1);
			Method method = o.getClass().getMethod(getter);
			Object value = method.invoke(o);
			return value;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public long getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}

	public String getSignature() {
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}
}
